package com.kuaiyin.utils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class JsonFieldFinder {
    /**
     *        String json = "json";
     *         JsonFieldFinder finder = new JsonFieldFinder(json);
     *
     *         // 查找第一个匹配的 dislike_show_list
     *         Object firstDislikeList = finder.findField("dislike_show_list", 0);
     *         System.out.println("第一个 dislike_show_list: " + firstDislikeList);
     */

    private static final ObjectMapper mapper = new ObjectMapper();
    private final JsonNode rootNode;

    public JsonFieldFinder(JsonNode json) throws IOException {
        this.rootNode = mapper.readTree(json.traverse());
    }

    /**
     * 递归查找 JSON 中所有匹配字段名的值
     * @param fieldName 要查找的字段名，如 "dislike_show_list"
     * @param index 当有多个匹配时的索引
     * @return 匹配的值，如果找不到返回 null
     */
    public Object findField(String fieldName, int index) {
        List<Object> results = new ArrayList<>();
        findFieldRecursive(rootNode, fieldName, results);

        if (index >= 0 && index < results.size()) {
            return results.get(index);
        }
        return null;
    }

    /**
     * 解析形如 {"caseid1": {"code": "0"}, "caseid2": {"id": "1"}} 的 JSON 配置，
     * 提取每个字段名和索引，并调用 findField(fieldName, index) 查找值，赋值给对应 key。
     * 查找不到或非法输入时返回 null 或跳过。
     *
     * @param configJson 配置 JSON 字符串
     * @return 包含提取结果的 Map，key 为配置中的 key（如 caseid1），value 为查找到的结果，可能为 null
     */
    public Map<String, Object> extractAndAssignMultipleFields(String configJson) {
        Map<String, Object> result = new HashMap<>();

        // 空输入直接返回空 map
        if (configJson == null || configJson.trim().isEmpty()) {
            return result;
        }

        try {
            JsonNode configNode = mapper.readTree(configJson);

            // 非对象或空对象也直接返回空 map
            if (!configNode.isObject() || configNode.isEmpty()) {
                return result;
            }

            configNode.fields().forEachRemaining(entry -> {
                String targetKey = entry.getKey();
                JsonNode fieldNode = entry.getValue();

                // 如果 value 不是对象或为空对象，则赋值 null 并跳过
                if (fieldNode == null || !fieldNode.isObject() || fieldNode.isEmpty()) {
                    result.put(targetKey, null);
                    return;
                }

                // 遍历字段定义 { "code": "0" }
                fieldNode.fields().forEachRemaining(fieldEntry -> {
                    String fieldName = fieldEntry.getKey();
                    JsonNode indexNode = fieldEntry.getValue();

                    // 如果不是基本类型（字符串/数字等），赋值 null
                    if (indexNode == null || !indexNode.isValueNode()) {
                        result.put(targetKey, null);
                        return;
                    }

                    String indexStr = indexNode.asText();
                    int index;

                    // 尝试解析索引
                    try {
                        index = Integer.parseInt(indexStr);
                    } catch (NumberFormatException e) {
                        result.put(targetKey, null);
                        return;
                    }

                    // 调用 findField 查找字段值
                    Object foundValue = findField(fieldName, index);
                    result.put(targetKey, foundValue);
                });
            });

        } catch (IOException e) {
            throw new RuntimeException("格式不合法", e);
        }

        return result;
    }


    /**
     * 递归查找 JSON 中所有匹配字段名的值
     * @param fieldName 要查找的字段名
     * @return 所有匹配值的列表
     */
    public List<Object> findAllFields(String fieldName) {
        List<Object> results = new ArrayList<>();
        findFieldRecursive(rootNode, fieldName, results);
        return results;
    }

    private void findFieldRecursive(JsonNode node, String fieldName, List<Object> results) {
        if (node.isObject()) {
            ObjectNode objectNode = (ObjectNode) node;

            // 检查当前对象是否有目标字段
            if (objectNode.has(fieldName)) {
                results.add(convertNodeToJavaObject(objectNode.get(fieldName)));
            }

            // 递归检查所有子字段
            objectNode.fields().forEachRemaining(entry -> {
                findFieldRecursive(entry.getValue(), fieldName, results);
            });
        } else if (node.isArray()) {
            ArrayNode arrayNode = (ArrayNode) node;

            // 递归检查数组中的每个元素
            arrayNode.forEach(element -> {
                findFieldRecursive(element, fieldName, results);
            });
        }
    }

    private Object convertNodeToJavaObject(JsonNode node) {
        if (node == null) {
            return null;
        }
        if (node.isTextual()) {
            return node.textValue();
        } else if (node.isNumber()) {
            return node.numberValue();
        } else if (node.isBoolean()) {
            return node.booleanValue();
        } else if (node.isArray()) {
            List<Object> list = new ArrayList<>();
            node.forEach(child -> list.add(convertNodeToJavaObject(child)));
            return list;
        } else if (node.isObject()) {
            return node;
        } else if (node.isNull()) {
            return null;
        }
        return node.toString();
    }
}